HEX
Server: Apache/2.4.68 (Debian)
System: Linux as-cs-widget-demo-us-central1 6.1.0-44-cloud-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.164-1 (2026-03-09) x86_64
User: root (0)
PHP: 8.2.32
Disabled: NONE
Upload Files
File: /var/www/html/wp-content/plugins/wp-recipe-maker/assets/js/admin-settings/menu/MenuContainer.js
import React, { useRef, useEffect } from 'react';
import PropTypes from 'prop-types'
import { Link } from 'react-scroll'

import Helpers from '../general/Helpers';
import Icon from '../general/Icon';
import Tooltip from 'Shared/Tooltip';

const MenuContainer = (props) => {
    const inputRef = useRef(null);
    
    // Sync uncontrolled input with controlled value when searchQuery changes externally
    useEffect(() => {
        if (inputRef.current && inputRef.current.value !== props.searchQuery) {
            inputRef.current.value = props.searchQuery;
        }
    }, [props.searchQuery]);
    
    let menuStructure = [];

    for ( let group of props.structure ) {
        if ( ! Helpers.dependencyMet(group, props.settings ) ) {
            continue;
        }

        if (group.hasOwnProperty('header')) {
            menuStructure.push({
                header: group.header,
            });
        } else {
            menuStructure.push({
                id: group.id,
                name: group.name,
                icon: group.hasOwnProperty( 'icon' ) ? group.icon : false,
            });
        }
    }

    const isSearchActive = props.searchQuery && props.searchQuery.length > 0;
    const changesSummary = props.changedSettingsCount
        ? `${props.changedSettingsCount} Change${1 === props.changedSettingsCount ? '' : 's'}`
        : 'No Changes';
    const searchSummary = props.searchResultsCount
        ? `${props.searchResultsCount} Result${1 === props.searchResultsCount ? '' : 's'}`
        : 'No Results';
    const changedSettingsBackLabel = isSearchActive ? 'Back to search results' : 'Back to categories';

    const clearSearch = () => {
        if (inputRef.current) {
            inputRef.current.value = '';
        }
        props.onSearchChange('');
    };

    const getChangedSettingContext = (changedSetting) => {
        if ( changedSetting.subgroupName ) {
            return `${changedSetting.groupName} > ${changedSetting.subgroupName}`;
        }

        return changedSetting.groupName;
    };

    const renderSearchSetting = (setting) => (
        <button
            type="button"
            className="wprm-settings-search-item"
            onClick={() => props.onJumpToSearchResult(setting)}
            key={setting.id}
        >
            {setting.name}
        </button>
    );

    return (
        <div id="wprm-settings-sidebar">
            <div id="wprm-settings-buttons">
                <div className="wprm-settings-changes-wrapper">
                    <div className="wprm-settings-changes-save-wrapper">
                        <button
                            className="button button-primary button-compact"
                            disabled={props.savingChanges || !props.settingsChanged}
                            onClick={props.onSaveChanges}
                        >{ props.savingChanges ? '...' : 'Save' }</button>
                    </div>
                    <Tooltip content={props.changedSettingsCount ? 'Click to review the changes that were made' : ''}>
                        <div className="wprm-settings-changes-summary-wrapper">
                            <button
                                type="button"
                                className={`button button-secondary button-compact wprm-settings-changes-summary${props.showChangedSettings ? ' active' : ''}`}
                                disabled={!props.changedSettingsCount}
                                onClick={props.onToggleChangedSettings}
                            >
                                {changesSummary}
                            </button>
                        </div>
                    </Tooltip>
                </div>
                <div className="wprm-settings-search-wrapper">
                    <input
                        ref={inputRef}
                        type="text"
                        id="wprm-settings-search"
                        placeholder="Search..."
                        defaultValue={props.searchQuery}
                        onChange={(e) => props.onSearchChange(e.target.value)}
                    />
                    {isSearchActive && (
                        <button
                            type="button"
                            className="wprm-settings-search-clear"
                            onClick={clearSearch}
                            title="Clear search"
                        >
                            ×
                        </button>
                    )}
                </div>
            </div>
            {props.showChangedSettings ? (
                <div id="wprm-settings-menu" className="wprm-settings-menu-changed">
                    <div className="wprm-settings-changed-back">
                        <a
                            href="#"
                            onClick={(e) => {
                                e.preventDefault();
                                props.onToggleChangedSettings();
                            }}
                        >
                            {changedSettingsBackLabel}
                        </a>
                    </div>
                    <div className="wprm-settings-menu-header">Changed settings</div>
                    <div className="wprm-settings-changed-list">
                        {
                            props.changedSettings.map((changedSetting) => (
                                <div
                                    className="wprm-settings-changed-item-row"
                                    key={changedSetting.id}
                                >
                                    <button
                                        type="button"
                                        className="wprm-settings-changed-item"
                                        onClick={() => props.onJumpToChangedSetting(changedSetting)}
                                    >
                                        <span className="wprm-settings-changed-item-name">{changedSetting.name}</span>
                                        <span className="wprm-settings-changed-item-context">{getChangedSettingContext(changedSetting)}</span>
                                        {
                                            changedSetting.isCurrentlyVisible
                                            ?
                                            null
                                            :
                                            <span className="wprm-settings-changed-item-badge">Hidden</span>
                                        }
                                    </button>
                                    <button
                                        type="button"
                                        className="wprm-settings-changed-item-cancel"
                                        aria-label={`Cancel change for ${changedSetting.name}`}
                                        onClick={() => props.onRevertChangedSetting(changedSetting.id)}
                                    >
                                        <Tooltip content={changedSetting.changeDescription}>
                                            <span className="wprm-settings-changed-item-cancel-icon" aria-hidden="true">
                                                <Icon type="undo" />
                                            </span>
                                        </Tooltip>
                                    </button>
                                </div>
                            ))
                        }
                    </div>
                    <div className="wprm-settings-changed-actions wprm-settings-changed-actions-bottom">
                        <button
                            type="button"
                            className="button button-secondary button-compact"
                            onClick={props.onCancelChanges}
                        >
                            Cancel All Changes
                        </button>
                    </div>
                </div>
            ) : isSearchActive ? (
                <div id="wprm-settings-menu" className="wprm-settings-menu-search">
                    <div className="wprm-settings-menu-header">Search results</div>
                    <div className="wprm-settings-search-summary">{searchSummary}</div>
                    {
                        props.searchResults.length ? (
                            <div className="wprm-settings-search-groups">
                                {
                                    props.searchResults.map((group) => (
                                        <div className="wprm-settings-search-group" key={group.id}>
                                            <button
                                                type="button"
                                                className="wprm-settings-search-group-button"
                                                onClick={() => props.onJumpToSearchResult({
                                                    targetType: 'section',
                                                    targetId: group.targetId,
                                                })}
                                            >
                                                { group.icon && <Icon type={group.icon} /> }
                                                <span>{group.name}</span>
                                            </button>
                                            {
                                                group.settings.length ? (
                                                    <div className="wprm-settings-search-items">
                                                        {group.settings.map(renderSearchSetting)}
                                                    </div>
                                                ) : null
                                            }
                                            {
                                                group.subgroups.length ? (
                                                    <div className="wprm-settings-search-subgroups">
                                                        {
                                                            group.subgroups.map((subgroup) => (
                                                                <div className="wprm-settings-search-subgroup" key={subgroup.id}>
                                                                    <button
                                                                        type="button"
                                                                        className="wprm-settings-search-subgroup-button"
                                                                        onClick={() => props.onJumpToSearchResult({
                                                                            targetType: 'section',
                                                                            targetId: subgroup.targetId,
                                                                        })}
                                                                    >
                                                                        {subgroup.name}
                                                                    </button>
                                                                    {
                                                                        subgroup.settings.length ? (
                                                                            <div className="wprm-settings-search-items">
                                                                                {subgroup.settings.map(renderSearchSetting)}
                                                                            </div>
                                                                        ) : null
                                                                    }
                                                                </div>
                                                            ))
                                                        }
                                                    </div>
                                                ) : null
                                            }
                                        </div>
                                    ))
                                }
                            </div>
                        ) : (
                            <div id="wprm-settings-menu-search-message">
                                No settings or sections match "{props.searchQuery}".
                            </div>
                        )
                    }
                    <div className="wprm-settings-search-footer">
                        <a href="#" onClick={(e) => { e.preventDefault(); clearSearch(); }}>
                            Clear search
                        </a>
                    </div>
                </div>
            ) : (
                <div id="wprm-settings-menu">
                    {
                        menuStructure.map((group, i) => {
                            if (group.hasOwnProperty('header')) {
                                return <div className="wprm-settings-menu-header" key={i}>{group.header}</div>
                            } else {
                                return <Link
                                        to={`wprm-settings-group-${group.id}`}
                                        className="wprm-settings-menu-group"
                                        activeClass="active"
                                        spy={true}
                                        offset={-42}
                                        smooth={true}
                                        duration={400}
                                        key={i}
                                    >
                                    { group.icon && <Icon type={group.icon} /> } {group.name}
                                </Link>
                            }
                        })
                    }
                </div>
            )}
        </div>
    );
}

MenuContainer.propTypes = {
    structure: PropTypes.array.isRequired,
    settings: PropTypes.object.isRequired,
    settingsChanged: PropTypes.bool.isRequired,
    savingChanges: PropTypes.bool.isRequired,
    onSaveChanges: PropTypes.func.isRequired,
    onCancelChanges: PropTypes.func.isRequired,
    searchQuery: PropTypes.string.isRequired,
    onSearchChange: PropTypes.func.isRequired,
    searchResults: PropTypes.array.isRequired,
    searchResultsCount: PropTypes.number.isRequired,
    onJumpToSearchResult: PropTypes.func.isRequired,
    changedSettings: PropTypes.array.isRequired,
    changedSettingsCount: PropTypes.number.isRequired,
    showChangedSettings: PropTypes.bool.isRequired,
    onToggleChangedSettings: PropTypes.func.isRequired,
    onJumpToChangedSetting: PropTypes.func.isRequired,
    onRevertChangedSetting: PropTypes.func.isRequired,
}

export default MenuContainer;